package com.whfc.base.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whfc.base.dao.AppMessageMapper;
import com.whfc.base.dto.MsgRecordDTO;
import com.whfc.base.dto.MsgStatisticsDTO;
import com.whfc.base.entity.AppMessage;
import com.whfc.base.enums.AppModuleType;
import com.whfc.base.param.WarnMsgSearchParam;
import com.whfc.base.service.MessageService;
import com.whfc.common.constant.QueueConst;
import com.whfc.common.enums.AppWarnMsgChannel;
import com.whfc.common.result.ListData;
import com.whfc.common.result.PageData;
import com.whfc.common.result.PageVO;
import com.whfc.common.result.PageVOUtil;
import com.whfc.common.util.JSONUtil;
import com.whfc.common.util.PageUtil;
import com.whfc.entity.dto.msg.*;
import com.whfc.fuum.entity.SysUser;
import com.whfc.fuum.service.SysDeptService;
import com.whfc.fuum.service.SysUserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2020-11-25 14:20
 */
@DubboService(interfaceClass = MessageService.class, version = "1.0.0")
public class MessageServiceImpl implements MessageService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @DubboReference(interfaceClass = SysDeptService.class, version = "1.0.0")
    private SysDeptService sysDeptService;

    @DubboReference(interfaceClass = SysUserService.class, version = "1.0.0")
    private SysUserService sysUserService;

    @Autowired
    private AppMessageMapper appMessageMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    public PageData<AppWarnMsgDTO> list(SysUser user, Integer pageNum, Integer pageSize, Integer deptId, Integer state, Integer moduleType) {
        logger.info("获取后台消息列表,deptId:{},phone:[],state:{},moduleType:{}", deptId, user.getPhone(), state, moduleType);
//        List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(deptId);

        PageHelper.startPage(pageNum, pageSize);
        List<AppWarnMsgDTO> list = appMessageMapper.selectWarnMsgDTOList(null, user.getPhone(), state, AppWarnMsgChannel.MS.value(), moduleType);
        PageHelper.clearPage();

        return PageUtil.pageData(PageInfo.of(list));
    }


    @Override
    public PageData<AppWarnMsgDTO> list(String userPhone, Integer pageNum, Integer pageSize, Integer deptId, Integer state, Integer moduleType) {
        logger.info("获取后台消息列表,deptId:{},phone:[],state:{},moduleType:{}", deptId, userPhone, state, moduleType);
//        List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(deptId);

        PageHelper.startPage(pageNum, pageSize);
        List<AppWarnMsgDTO> list = appMessageMapper.selectWarnMsgDTOList(null, userPhone, state, AppWarnMsgChannel.MS.value(), moduleType);
        PageHelper.clearPage();

        return PageUtil.pageData(PageInfo.of(list));
    }

    @Override
    public AppMsgNumDTO getUnreadMsgNum(SysUser user, Integer deptId) {
        logger.info("获取后台消息未读数量,deptId:{},phone:[]", deptId, user.getPhone());
//        List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(deptId);
        List<AppMsgModuleTypeNumDTO> list = appMessageMapper.selectUnreadMsgNumDTOList(null, user.getPhone(), AppWarnMsgChannel.MS.value());
        Integer total = 0;
        AppMsgNumDTO appMsgNumDTO = new AppMsgNumDTO();
        for (AppMsgModuleTypeNumDTO msgModuleTypeNumDTO : list) {
            Integer moduleType = msgModuleTypeNumDTO.getModuleType();
            Integer num = msgModuleTypeNumDTO.getNum();
            total += num;
            switch (moduleType) {
                case 1:
                    appMsgNumDTO.setMachMsgNum(num);
                    break;
                case 2:
                    appMsgNumDTO.setEmpMsgNum(num);
                    break;
                case 3:
                    appMsgNumDTO.setFmamMsgNum(num);
                    break;
                case 4:
                    appMsgNumDTO.setEnvMsgNum(num);
                    break;
                case 5:
                    appMsgNumDTO.setFimMsgNum(num);
                    break;
                case 6:
                    appMsgNumDTO.setFseMsgNum(num);
                    break;
                case 7:
                    appMsgNumDTO.setEquipMsgNum(num);
                    break;
                case 8:
                    appMsgNumDTO.setQualityMsgNum(num);
                    break;
                case 9:
                    appMsgNumDTO.setSafetyMsgNum(num);
                    break;
                default:
                    break;
            }
        }
        appMsgNumDTO.setTotal(total);
        return appMsgNumDTO;
    }
    @Override
    public AppMsgNumDTO getUnreadMsgNum(String phone, Integer deptId) {
        logger.info("获取后台消息未读数量,deptId:{},phone:[]", deptId, phone);
//        List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(deptId);
        List<AppMsgModuleTypeNumDTO> list = appMessageMapper.selectUnreadMsgNumDTOList(null, phone, AppWarnMsgChannel.MS.value());
        Integer total = 0;
        AppMsgNumDTO appMsgNumDTO = new AppMsgNumDTO();
        for (AppMsgModuleTypeNumDTO msgModuleTypeNumDTO : list) {
            Integer moduleType = msgModuleTypeNumDTO.getModuleType();
            Integer num = msgModuleTypeNumDTO.getNum();
            total += num;
            switch (moduleType) {
                case 1:
                    appMsgNumDTO.setMachMsgNum(num);
                    break;
                case 2:
                    appMsgNumDTO.setEmpMsgNum(num);
                    break;
                case 3:
                    appMsgNumDTO.setFmamMsgNum(num);
                    break;
                case 4:
                    appMsgNumDTO.setEnvMsgNum(num);
                    break;
                case 5:
                    appMsgNumDTO.setFimMsgNum(num);
                    break;
                case 6:
                    appMsgNumDTO.setFseMsgNum(num);
                    break;
                case 7:
                    appMsgNumDTO.setEquipMsgNum(num);
                    break;
                case 8:
                    appMsgNumDTO.setQualityMsgNum(num);
                    break;
                case 9:
                    appMsgNumDTO.setSafetyMsgNum(num);
                    break;
                default:
                    break;
            }
        }
        appMsgNumDTO.setTotal(total);
        return appMsgNumDTO;
    }

    @Override
    public void addMessage(List<AppMessage> messageList) {
        if (messageList != null && messageList.size() > 0) {
            appMessageMapper.batchInsert(messageList);
        }
    }

    @Override
    public void addWarnMessage(Integer moduleType, List<AppMsgToUserDTO> userList, List<Integer> msgChannelList, String title, String content, String msgObjectId, Integer deptId, Date time) {
        if (userList == null || userList.size() == 0) {
            return;
        }
        if (msgChannelList == null || msgChannelList.size() == 0) {
            return;
        }

        PushMsgDTO pushMsgDTO = new PushMsgDTO();
        pushMsgDTO.setDeptId(deptId);
        pushMsgDTO.setTitle(title);
        pushMsgDTO.setContent(content);
        pushMsgDTO.setModuleType(moduleType);
        pushMsgDTO.setMsgObjectId(msgObjectId);
        pushMsgDTO.setMsgChannelList(msgChannelList);
        pushMsgDTO.setToUserList(userList);
        pushMsgDTO.setTime(time);

        try {
            amqpTemplate.convertAndSend(QueueConst.PUSH_MSG_EXCHANGE, "", JSONUtil.toString(pushMsgDTO));
        } catch (Exception ex) {
            logger.error("", ex);
        }
    }

    @Override
    public void del(List<Integer> idList) {
        logger.info("删除消息,idList:{}", idList);
        if (idList != null && idList.size() > 0) {
            appMessageMapper.deleteLogicByIds(idList);
        }
    }

    @Override
    public void delAll(String phone, Integer deptId, Integer moduleType, Integer state) {
        logger.info("删除消息,userId:{},deptId:{},moduleType:{},state:{}", phone, deptId, moduleType, state);
        appMessageMapper.delLogicByUserPhoneAndDeptId(phone, deptId, moduleType, state);
    }

    @Override
    public void read(List<Integer> idList) {
        if (idList != null && idList.size() > 0) {
            appMessageMapper.batchUpdateMsgRead(idList, new Date());
        }

    }

    @Override
    public void readAll(String phone, Integer deptId, Integer moduleType) {
        appMessageMapper.updateMsgReadByUserPhoneAndDeptId(phone, deptId, moduleType);
    }

    @Override
    public void updateSmsState(Integer id) {
        appMessageMapper.updateSmsState(id);
    }

    @Override
    public ListData<AppWarnMsgDTO> getWarnGeneral(Integer deptId, String phone) {
        logger.info("获取小程序消息概况,deptId:{},phone:{}", deptId, phone);
//        List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(deptId);
        List<AppWarnMsgDTO> list = appMessageMapper.selectWxUnreadMsgNumList(null, phone, AppWarnMsgChannel.WXMP.value());
        for (AppWarnMsgDTO appWarnMsgDTO : list) {
            Integer moduleType = appWarnMsgDTO.getModuleType();

            List<AppMsgModuleTypeNumDTO> unreadMsgNumDTOListlist = appMessageMapper.selectUnreadMsgNumDTOList(null, phone, AppWarnMsgChannel.WXMP.value());
            for (AppMsgModuleTypeNumDTO msgModuleTypeNumDTO : unreadMsgNumDTOListlist) {
                if (moduleType.equals(msgModuleTypeNumDTO.getModuleType())) {
                    appWarnMsgDTO.setUnReadNum(msgModuleTypeNumDTO.getNum());
                }
            }
        }
        return new ListData<>(list);
    }

    @Override
    public PageData<AppWarnMsgDTO> getWarnMsgList(Integer deptId, String phone, Integer handleState, Integer moduleType, Integer pageNum, Integer pageSize) {
        logger.info("获取小程序消息列表,deptId:{},phone:{},handleState:{},moduleType:{},pageNum:{},pageSize:{}", deptId, phone, handleState, moduleType, pageNum, pageSize);
//        List<Integer> deptIdList = sysDeptService.getDescendantDeptIdList(deptId);

        PageHelper.startPage(pageNum, pageSize);
        List<AppWarnMsgDTO> warnMsgDTOList = appMessageMapper.selectWarnMsgDTOList(null, phone, null, AppWarnMsgChannel.WXMP.value(), moduleType);
        PageHelper.clearPage();

        return PageUtil.pageData(PageInfo.of(warnMsgDTOList));
    }

    @Override
    public List<MsgStatisticsDTO> getWarnMsgStatistics(Integer deptId, Integer warnType, Integer userId) {

//        List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(deptId);
        List<Integer> moduleTypes = AppModuleType.WarnMessageEnum.getModuleTypes(warnType);

        //1-已读 0-未读
        Integer state = 0;
        List<MsgStatisticsDTO> list = appMessageMapper.selectWarnMsgStatistics(null, moduleTypes, userId, AppWarnMsgChannel.WXMP.value(), state);

        Map<Integer, Long> map = new HashMap<>();
        list.forEach(k -> map.put(k.getModuleType(), k.getMessageCount()));

        List<MsgStatisticsDTO> dataList = new ArrayList<>();
        for (Integer moduleType : moduleTypes) {
            MsgStatisticsDTO v = new MsgStatisticsDTO();
            v.setModuleType(moduleType);
            v.setMessageCount(map.getOrDefault(moduleType, 0L));
            v.setTime(appMessageMapper.selectLastTime(null, moduleType, userId, AppWarnMsgChannel.WXMP.value(), null));
            dataList.add(v);
        }

        List<MsgStatisticsDTO> res = dataList.stream().filter(m -> m.getTime() != null).sorted(Comparator.comparing(MsgStatisticsDTO::getTime).reversed()).collect(Collectors.toList());
        List<MsgStatisticsDTO> tempList = dataList.stream().filter(n -> n.getTime() == null).sorted(Comparator.comparing(MsgStatisticsDTO::getModuleType)).collect(Collectors.toList());
        for (MsgStatisticsDTO t : tempList) {
            res.add(t);
        }
        return res;
    }

    @Override
    public PageVO<MsgRecordDTO> getWarnMsgPage(WarnMsgSearchParam param) {

//        List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(param.getDeptId());
//        param.setDeptIds(deptIds);

        PageVOUtil.startPage(param);
        List<MsgRecordDTO> list = appMessageMapper.selectWarnMsgPage(param);
        PageVOUtil.clearPage();

        return PageVOUtil.page(PageInfo.of(list));
    }

    @Override
    public void addAppMessage(List<AppMessage> appMessages) {
        appMessageMapper.batchInsert(appMessages);
    }

    @Override
    public List<AppMessage> searchAllByMsgObjectId(String msgObjectId) {
        return appMessageMapper.searchAllByMsgObjectId(msgObjectId);
    }

}
